package com.load.ctrls.imp;

import java.math.BigDecimal;
import java.util.*;

import com.database.objects.*;
import com.load.ctrls.IDeveloperCtrl;
import com.metrics.extractors.*;
import com.metrics.objects.*;

public class DeveloperCtrl implements IDeveloperCtrl {

	private static final long serialVersionUID = -8067657047683407785L;

	private MetricExtractorMap metricExtractorMap;

	@Override
	public void filterMaxDevelopersByPercent(List<Developer> developers, Options options) {
		Metric metric = options.getMetric();
		Type type = options.getType();
		Status status = options.getStatus();
		String start = options.getStart();
		String finish = options.getFinish();
		BigDecimal percent = options.getPercent();
		boolean orderByName = options.isOrderByName();

		MetricExtractor extractor = metricExtractorMap.get(metric);
		for (Developer developer : developers) {
			developer.setValue(extractor.extract(developer, type, status, start, finish));
		}
		orderDevelopersByValue(developers);
		filterMaxDevelopersByPercent(developers, percent);
		orderDevelopersByName(developers, orderByName);
	}

	private void orderDevelopersByValue(List<Developer> developers) {
		Collections.sort(developers, new Comparator<Developer>() {
			@Override
			public int compare(Developer dev1, Developer dev2) {
				return dev1.getValue().compareTo(dev2.getValue());
			}
		});
	}

	private void filterMaxDevelopersByPercent(List<Developer> developers, BigDecimal percent) {
		int total = developers.size();
		int numDevelopers = new BigDecimal(total).multiply(percent.divide(new BigDecimal(100))).setScale(0, BigDecimal.ROUND_UP).intValue();

		Iterator<Developer> iterator = developers.iterator();
		int index = 0;
		while (iterator.hasNext()) {
			iterator.next();
			if (index < (total - numDevelopers)) {
				iterator.remove();
			}
			index++;
		}
	}

	private void orderDevelopersByName(List<Developer> developers, boolean orderByName) {
		if (orderByName) {
			Collections.sort(developers, new Comparator<Developer>() {
				@Override
				public int compare(Developer dev1, Developer dev2) {
					return dev1.getName().compareTo(dev2.getName());
				}
			});
		}
	}

	@Override
	public void filterDevelopersByName(List<Developer> developers, Options options) {
		String name = options.getNameDeveloper();
		if (!name.equals("")) {
			Iterator<Developer> iterator = developers.iterator();
			while (iterator.hasNext()) {
				Developer developer = iterator.next();
				if (!developer.getName().equals(name)) {
					iterator.remove();
				}
			}
		}
	}

	public void setMetricExtractorMap(MetricExtractorMap metricExtractorMap) {
		this.metricExtractorMap = metricExtractorMap;
	}

}